﻿using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.UI;

namespace Nirvana
{
    /// <summary>
    /// 字体间隔
    /// </summary>
    [AddComponentMenu("Nirvana/UI/Effects/Letter Spacing")]
    [RequireComponent(typeof(Text))]
    public class UILetterSpacing : BaseMeshEffect
    {
        [SerializeField]
        private float spacing;
        private const string _defaultXml = "<b>|</b>|<i>|</i>|<size=.*?>|</size>|<color=.*?>|</color>|<material=.*?>|</material>";
        private const int _count = 6;


#if UNITY_EDITOR
        protected override void OnValidate()
        {
            base.OnValidate();
            if (base.graphic != null)
            {
                base.graphic.SetVerticesDirty();
            }
        }
#endif


        public override void ModifyMesh(VertexHelper vh)
        {
            if (!this.IsActive() || vh.currentVertCount <= 0)
            {
                return;
            }
            Text txt = GetComponent<Text>();
            if (txt == null)
            {
                Debug.LogWarning("LetterSpacing: Missing Text component");
                return;
            }
            List<UIVertex> tempList = VertexLists.Get();
            vh.GetUIVertexStream(tempList);
            List<UIVertex> newlist = ModifyVertex(tempList, txt,spacing);
            if (newlist != null)
            {
                vh.Clear();
                vh.AddUIVertexTriangleStream(newlist);
            }
            VertexLists.Set(newlist);
        }

        private List<UIVertex> ModifyVertex(List<UIVertex> _list, Text txt, float spacing)
        {
            List<string> list = new List<string>();
            for (int i = 0; i < txt.cachedTextGenerator.lineCount; i++)
            {
                int startCharIdx = txt.cachedTextGenerator.lines[i].startCharIdx;
                int num = (i >= txt.cachedTextGenerator.lineCount - 1) ? txt.text.Length : txt.cachedTextGenerator.lines[i + 1].startCharIdx;
                list.Add(txt.text.Substring(startCharIdx, num - startCharIdx));
            }
            float num2 = 0f;
            switch (txt.alignment)
            {
                case 0:
                case TextAnchor.MiddleLeft:
                case TextAnchor.LowerLeft:
                    num2 = 0f;
                    break;
                case TextAnchor.UpperCenter:
                case TextAnchor.MiddleCenter:
                case TextAnchor.LowerCenter:
                    num2 = 0.5f;
                    break;
                case TextAnchor.UpperRight:
                case TextAnchor.MiddleRight:
                case TextAnchor.LowerRight:
                    num2 = 1f;
                    break;
            }
            float num3 = spacing * (float)txt.fontSize;
            IEnumerator enumerator = null;
            Match match = null;
            bool flag = true;
            int num4 = 0;
            int num5 = 0;
            while (num5 < list.Count && flag)
            {
                string text = list[num5];
                int num6 = text.Length;
                if (num6 > txt.cachedTextGenerator.characterCountVisible - num4)
                {
                    num6 = txt.cachedTextGenerator.characterCountVisible - num4;
                    text = text.Substring(0, num6) + " ";
                    num6++;
                }
                if (txt.supportRichText)
                {
                    enumerator = this.MatchString(text, out num6).GetEnumerator();
                    match = null;
                    if (enumerator.MoveNext())
                    {
                        match = (Match)enumerator.Current;
                    }
                }
                bool flag2 = list[num5].Length > 0 && (list[num5][list[num5].Length - 1] == ' ' || list[num5][list[num5].Length - 1] == '\n');
                float num7 = (float)(-(float)(num6 - 1 - ((!flag2) ? 0 : 1))) * num3 * num2;
                float num8 = 0f;
                int num9 = 0;
                while (num9 < text.Length && flag)
                {
                    if (txt.supportRichText && match != null && match.Index == num9)
                    {
                        num9 += match.Length - 1;
                        num4 += match.Length - 1;
                        num8 -= 1f;
                        match = null;
                        if (enumerator.MoveNext())
                        {
                            match = (Match)enumerator.Current;
                        }
                    }
                    if (num4 * 6 + 5 >= _list.Count)
                    {
                        flag = false;
                        break;
                    }
                    for (int j = 0; j < 6; j++)
                    {
                        UIVertex value = _list[num4 * 6 + j];
                        value.position += Vector3.right * (num3 * num8 + num7);
                        _list[num4 * 6 + j] = value;
                    }
                    num4++;
                    num8 += 1f;
                    num9++;
                }
                num5++;
            }
            return _list;
        }

        private MatchCollection MatchString(string src, out int len)
        {
            MatchCollection matchCollection = Regex.Matches(src, "<b>|</b>|<i>|</i>|<size=.*?>|</size>|<color=.*?>|</color>|<material=.*?>|</material>");
            len = 0;
            int num = 0;
            foreach (object obj in matchCollection)
            {
                Match match = (Match)obj;
                num += match.Length;
            }
            len = src.Length - num;
            return matchCollection;
        }


    }
}

